#pragma once
#include <signal.h>
#include "Acceptor.hpp"
//对所有模块的整合，提供给外部使用者使用
class TcpServer
{
public:
    TcpServer(int port)
        :_port(port)
        ,_nextId(0) 
        ,_enableInactiveRelease(false)
        ,_acceptor(&_baseLoop, port)
        ,_pool(&_baseLoop)
    {
        _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));//获取新连接后的回调函数的设置
        _acceptor.Listen();//将监听套接字挂到baseloop上，启动读事件监控
    }
public:
    //设置从属EventLoop线程池中线程的数量
    void SetThreadCount(int count) { return _pool.SetThreadCount(count); }
    //启动非活跃连接的超时销毁功能
    void EnableInactiveReleanse(int timeout)
    {
        _timeout = timeout;
        _enableInactiveRelease = true;
    }
    //多少秒之后执行一次任务,用于添加一个定时任务
    void RunAfter(const Functor& task, int delay)
    {
        _baseLoop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
    }
    //启动服务器
    void Start()
    {
        _pool.Create();//创建所有从属线程
        _baseLoop.StartEventLoop();
    }
    //设置连接的回调函数
    void SetConnectedCallBack(const ConnectedCallBack& callback) { _connectedCallBack = callback; }
    //设置消息的回调函数
    void SetMessageCallBack(const MessageCallBack& callback) { _messageCallBack = callback; }
    //设置关闭的回调函数 
    void SetClosedCallBack(const ClosedCallBack& callback) { _closedCallBack = callback; }
    //设置任意事件的回调函数
    void SetAnyEventCallBack(const AnyEventCallBack& callback) { _anyEventCallBack = callback; } 
private:
    //监听套接字获取新连接的调用函数,为新连接构造一个Connection进行管理
    void NewConnection(int fd)
    {
        _nextId++;
        PtrConnection conn(new Connection(_pool.NextLoop(), _nextId, fd));
        conn->SetMessageCallBack(_messageCallBack);
        conn->SetClosedCallBack(_closedCallBack);
        conn->SetConnectedCallBack(_connectedCallBack);//等于accept
        conn->SetAnyEventCallBack(_anyEventCallBack);
        conn->SetServerClosedCallBack(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        if(_enableInactiveRelease) { conn->EnableInactiveRelease(_timeout); };//添加定时任务，启动非活跃的连接销毁,超过timeout即视为非活跃
        conn->Established();//给channel设置事件回调，启动读监控，调用连接完成的回调：_connectedCallBack
        _conns.insert(std::make_pair(_nextId, conn));
    }
    //从管理的Connection的_conns中移除连接信息
    void RemoveConnection(const PtrConnection& conn)
    {
        _baseLoop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
    }
    void RemoveConnectionInLoop(const PtrConnection& conn)
    {
        int id = conn->GetConnId();
        auto it = _conns.find(id);
        if (it != _conns.end())
        {
            _conns.erase(it);
        }
    }
    //多少秒之后执行一次任务,用于添加一个定时任务
    void RunAfterInLoop(const Functor& task, int delay)
    {
        _nextId++;
        _baseLoop.TimerAdd(_nextId, delay, task);//添加定时器任务
    }
private:
    int _port;//服务器用于监听的端口
    uint64_t _nextId;//这是一个自动增长的连接id
    int _timeout;//多长时间无通信就是非活跃连接
    bool _enableInactiveRelease;//关闭/开启非活跃连接的超时销毁功能
    EventLoop _baseLoop;//主线程的EventLoop对象，负责监听事件的处理
    Acceptor _acceptor;//管理监听套接字对象
    LoopThreadPool _pool;//从属EventLoop线程池
    std::unordered_map<uint64_t, PtrConnection> _conns;//保存管理所有连接的shared_ptr
    //这四个回调函数，是让组件使用者通过服务器模块进行设置
    ConnectedCallBack _connectedCallBack;//
    MessageCallBack _messageCallBack;//
    ClosedCallBack _closedCallBack;//
    AnyEventCallBack _anyEventCallBack;//组件使用者的任意事件回调
};

//当连接断开还进行send，服务器就会出现SIGPIPE异常，导致程序退出，需要屏蔽
class NetWorker
{
public: 
    NetWorker()
    {
        DEBUG_LOG("SIGPIPE INIT");
        signal(SIGPIPE, SIG_IGN);
    }
};
static NetWorker nw;//静态变量，将在main函数执行前生成